package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.mapper.BpmnInfoMapper;
import cn.wolfcode.car.business.query.BpmnInfoQuery;
import cn.wolfcode.car.business.service.IBpmnInfoService;
import cn.wolfcode.car.common.base.page.TablePage;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.config.SystemConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
@Transactional
public class BpmnInfoServiceImpl extends ServiceImpl<BpmnInfoMapper, BpmnInfo> implements IBpmnInfoService {

    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;
    @Autowired
    private RepositoryService repositoryService;

    @Override
    public TablePage<BpmnInfo> query(BpmnInfoQuery qo) {
        Page<BpmnInfo> page = new Page<>(qo.getPageNum(),qo.getPageSize());
        QueryWrapper<BpmnInfo> wrapper = Wrappers.<BpmnInfo>query();
        wrapper.ge(qo.getBeginTime() != null,"deploy_time",qo.getBeginTime());
        wrapper.le(qo.getEndTime() != null,"deploy_time",qo.getEndTime());
        bpmnInfoMapper.selectPage(page, wrapper);
        return new TablePage<BpmnInfo>(page);
    }

    @Override
    public void add(BpmnInfo bpmnInfo) {
        bpmnInfoMapper.insert(bpmnInfo);
    }

    @Override
    public BpmnInfo get(Long id) {
        return bpmnInfoMapper.selectById(id);
    }


    @Override
    public void update(BpmnInfo bpmnInfo) {
        bpmnInfoMapper.updateById(bpmnInfo);
    }

    @Override
    public void delete(Long id) {
        // 除了删除bpmnInfo对象,还要删除流程定义对象
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectById(id);
        // 删除bpmnInfo对象
        bpmnInfoMapper.deleteById(id);
        // 删除流程定义对象
        repositoryService.deleteDeployment(bpmnInfo.getDeploymentId(),true);
    }

    @Override
    public void deploy(String path, String bpmnType, String info) throws FileNotFoundException {
        // 根据路径获取文件
        File file = new File(SystemConfig.getProfile() + path);
        // 部署流程定义
        Deployment deployment = repositoryService.createDeployment().addInputStream(file.getName(),new FileInputStream(file)).deploy();
        ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
        // 创建bpmnInfo对象
        BpmnInfo bpmnInfo = new BpmnInfo();
        bpmnInfo.setBpmnName(definition.getName());
        bpmnInfo.setBpmnType(bpmnType);
        bpmnInfo.setDeploymentId(deployment.getId());
        bpmnInfo.setActProcessId(definition.getId());
        bpmnInfo.setActProcessKey(definition.getKey());
        bpmnInfo.setDeployTime(new Date());
        bpmnInfo.setInfo(info);
        // 保存bpmnInfo对象
        bpmnInfoMapper.insert(bpmnInfo);
    }

    @Override
    public InputStream readResource(Long deploymentId, String type) {
        // 如果是xml格式直接返回xml文件即可,如果是png格式需要使用到activiti提供的绘图插件
        // 首先获取数据库中保存的流程定义的文件
        List<ProcessDefinition> list = Collections.unmodifiableList(repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId.toString()).orderByProcessDefinitionVersion().desc().list());
        ProcessDefinition definition = list.get(0);
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId.toString(), definition.getResourceName());
        // 如果是png格式,通过DefaultProcessDiagramGenerator 绘制成图片
        if ("png".equals(type)) {
            DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
            // 第一个参数通过repositoryService可以获取,第二个是高亮节点,第三个是高亮线段,后面三个是为了解决中文乱码问题
            inputStream = generator.generateDiagram(repositoryService.getBpmnModel(definition.getId()),
                    Collections.EMPTY_LIST,Collections.EMPTY_LIST,"宋体","宋体","宋体");
        }
        // 如果不是Png格式直接返回
        return inputStream;
    }

    @Override
    public BpmnInfo queryByType(String type) {
        QueryWrapper<BpmnInfo> wrapper = Wrappers.<BpmnInfo>query();
        wrapper.eq("bpmn_type",type);
        return bpmnInfoMapper.selectOne(wrapper);
    }
}
